package cn.ilikes.tools.nosql.jpa.classloads.porxys;

import java.util.HashMap;
import java.util.Map;

import cn.ilikes.tools.nosql.jpa.JPASQLPersistenUnitEnv;
import cn.ilikes.tools.nosql.jpa.clients.AbClient;
import cn.ilikes.tools.nosql.jpa.metadatas.EntityMetaData;
import cn.ilikes.tools.nosql.jpa.metadatas.elements.EntityFields;
import cn.ilikes.tools.nosql.jpa.persistences.contexts.AbstractContext;

public class CglibLazyInitializerFactory implements LazyInitializerFactory {

	private LazyInitializers cglibLayInitializerList;

	private Map<EntityMetaData, LazyInitializers> entityLazyInitializers = new HashMap<EntityMetaData, LazyInitializers>();

	public CglibLazyInitializerFactory() {

	}

	private void setCglibLayInitializerList(LazyInitializers cglibLayInitializerList) {
		this.cglibLayInitializerList = cglibLayInitializerList;
	}

	private void addEntityLazyInitializers(EntityMetaData entityMetaData, LazyInitializers lazyInitializers) {
		entityLazyInitializers.put(entityMetaData, lazyInitializers);
	}

	@Override
	public Object getProxy(EntityFields entityFields, EntityMetaData targetEntityMetaData, Object keyId, AbstractContext abstractContext) {

		LazyInitializers lazyInitializers = new CglibLazyInitializer(entityFields, targetEntityMetaData, keyId, abstractContext);

		return lazyInitializers.getProxy();
	}

	//	Object keyId = PropertyAccessorHelper.getId(entity, entityMetaData);
	@Override
	public Object getListProxy(AbClient client, EntityFields entityFields, Object entity, JPASQLPersistenUnitEnv persistenUnitEnv) {

		if (cglibLayInitializerList == null) {
			synchronized (entity) {
				cglibLayInitializerList = new CglibLayInitializerList(client, entityFields, entity, persistenUnitEnv);
				setCglibLayInitializerList(cglibLayInitializerList);
			}

		}

		return cglibLayInitializerList.getProxy();
	}

	@Override
	public Object getProxy(EntityMetaData entityMetaData, Object keyId, AbstractContext abstractContext) {

		LazyInitializers lazyInitializers = entityLazyInitializers.get(entityMetaData);
		if (lazyInitializers == null) {
			synchronized (keyId) {
				lazyInitializers = new CglibLayInitializerEntity(entityMetaData, keyId, abstractContext);
				addEntityLazyInitializers(entityMetaData, lazyInitializers);
			}
		}
		return lazyInitializers.getProxy();
	}

}
